package mapeditor;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JOptionPane;
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import mapeditor.*;

/**
 *
 * @author  tamastoth
 */
public class mainWnd extends javax.swing.JFrame {
    //private jAnyComponent form = null;
	
		JButton buttons[][] = new JButton[14][20];
		String data[][] = new String[14][20];
		
		final ImageIcon enemy = new javax.swing.ImageIcon(getClass().getResource("/resources/skull.png"));
		final ImageIcon wall = new javax.swing.ImageIcon(getClass().getResource("/resources/wall.jpg"));
		final ImageIcon start = new javax.swing.ImageIcon(getClass().getResource("/resources/start.jpg"));
		final ImageIcon end = new javax.swing.ImageIcon(getClass().getResource("/resources/finish.png"));		
	
    /** Creates new form mainWnd */
    public mainWnd() {
        initComponents();				
				
				JPanel buttonPanel = new JPanel();
        //JPanel containerPanel = new JPanel();																				
				
        buttonPanel.setLayout(new GridLayout(14, 20, 0, 0));
				
				for (int i = 0; i < 14; i++)	{
					for (int j = 0; j < 20; j++)	{
						data[i][j] = "none";
						buttons[i][j] = new JButton();
						//buttons[i][j].setLabel(Integer.toString(j) + ", " + Integer.toString(i));
						buttons[i][j].setName("button_"+i+"_"+j);
						
						buttons[i][j].addActionListener(new java.awt.event.ActionListener() {
							public void actionPerformed(java.awt.event.ActionEvent evt) {
								JButton button = (JButton) evt.getSource();
								Icon current = button.getIcon();							
								
								int i = Integer.parseInt(button.getName().split("_")[1]);
								int j = Integer.parseInt(button.getName().split("_")[2]);
								
								String actual = data[i][j];
								
								System.out.println(data[i][j]);
								
								//button.getIcon(null)
								if (actual.equals("none")) {									
									button.setIcon(wall);		
									data[i][j] = "wall";
								}
								if (actual.equals("wall")) {
									button.setIcon(enemy);
									data[i][j] = "enemy";
								}
								if (actual.equals("enemy")) {
									button.setIcon(start);
									data[i][j] = "start";
								}
								if (actual.equals("start")) {
									button.setIcon(end);
									data[i][j] = "end";
								}
								if (actual.equals("end")) {
									button.setIcon(null);
									data[i][j] = "none";
								}

							}
						});	
						
						buttons[i][j].addMouseListener(new MouseAdapter() {	
								@Override
								public void mouseClicked(MouseEvent e) {
									int type = e.getButton();
									JButton button = (JButton) e.getSource();
									
									int i = Integer.parseInt(button.getName().split("_")[1]);
									int j = Integer.parseInt(button.getName().split("_")[2]);
									
									if (type == 3) { // if right click
											button.setIcon(null);											
											data[i][j] = "none";
									}
								}
						});
						
						buttonPanel.add(buttons[i][j]);
					}
				}
								
        buttonPanel.setPreferredSize(new Dimension(1000, 700));				
        //containerPanel.add(buttonPanel);
				//this.getContentPane().add(containerPanel);
        this.getContentPane().add(buttonPanel);
        this.pack();
        //this.setVisible(true);
    }

    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jMenuItem1 = new javax.swing.JMenuItem();
    jMenuBar1 = new javax.swing.JMenuBar();
    jFileMenu = new javax.swing.JMenu();
    jMenuItem2 = new javax.swing.JMenuItem();
    jLoadMenu = new javax.swing.JMenuItem();
    jSaveMenu = new javax.swing.JMenuItem();
    jSeparator1 = new javax.swing.JSeparator();
    jQuitMenu = new javax.swing.JMenuItem();

    jMenuItem1.setText("jMenuItem1");

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jFileMenu.setText("Fájl");
    jFileMenu.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jFileMenuActionPerformed(evt);
      }
    });

    jMenuItem2.setText("Új");
    jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jMenuItem2ActionPerformed(evt);
      }
    });
    jFileMenu.add(jMenuItem2);

    jLoadMenu.setText("Megnyitás");
    jLoadMenu.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jLoadMenuActionPerformed(evt);
      }
    });
    jFileMenu.add(jLoadMenu);

    jSaveMenu.setText("Mentés");
    jSaveMenu.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jSaveMenuActionPerformed(evt);
      }
    });
    jFileMenu.add(jSaveMenu);
    jFileMenu.add(jSeparator1);

    jQuitMenu.setText("Kilépés");
    jQuitMenu.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jQuitMenuActionPerformed(evt);
      }
    });
    jFileMenu.add(jQuitMenu);

    jMenuBar1.add(jFileMenu);

    setJMenuBar(jMenuBar1);

    pack();
  }// </editor-fold>//GEN-END:initComponents

    private void jSaveMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jSaveMenuActionPerformed
// TODO add your handling code here:
				//String actual_data[][] = new String[14][20];
				//actual_data = data;
			
        mapeditor.OpenDlg dlg = new OpenDlg(this, true, false);
				dlg.setVisible(true);
				File f=dlg.getFile();
				if (f != null) {						
					try {
						FileWriter w = new FileWriter(f);
						
						DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
						DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

						// root elements
						Document doc = docBuilder.newDocument();
						Element rootElement = doc.createElement("map");
						doc.appendChild(rootElement);

						Element start = doc.createElement("start");
						start.setAttribute("x", "0");
						start.setAttribute("y", "0");
						
						for (int i = 0; i < 14; i++)	{
							for (int j = 0; j < 20; j++)	{
								if(data[i][j].equals("start"))	{
									int x = this.getCoordinateX(j);
									int y = this.getCoordinateY(i);									
									
									start.setAttribute("x", Integer.toString(x));
									start.setAttribute("y", Integer.toString(y));
								}
							}
						}	
						rootElement.appendChild(start);						

						Element goal = doc.createElement("goal");
						goal.setAttribute("x", "0");
						goal.setAttribute("y", "0");
						for (int i = 0; i < 14; i++)	{
							for (int j = 0; j < 20; j++)	{
								if(data[i][j].equals("end"))	{
									int x = this.getCoordinateX(j);;									
									int y = this.getCoordinateY(i);
									
									goal.setAttribute("x", Integer.toString(x));
									goal.setAttribute("y", Integer.toString(y));
								}
							}
						}
						rootElement.appendChild(goal);						
						
						// Falak
						Element walls = doc.createElement("walls");
						rootElement.appendChild(walls);

						// Vízszintes falak feltérképezése						
						int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
						boolean empty = true;
						
						for (int i = 0; i < 14; i++)	{
							for (int j = 0; j < 20; j++)	{
								if(data[i][j].equals("wall"))	{
									int x = this.getCoordinateX(j);									
									int y = this.getCoordinateY(i);
									
									if(empty)	{
										empty = false;
										x1 = x2 = x;
										y1 = y2 = y;
									}
									else	{
										x2 = x;
										y2 = y;
									}
									
									
								}
								else	{
									if(empty == false)	{
										if( x1 != x2 || y1 != y2)	{
											Element wall = doc.createElement("wall");
											wall.setAttribute("x1", Integer.toString(x1));
											wall.setAttribute("y1", Integer.toString(y1));
											wall.setAttribute("x2", Integer.toString(x2));
											wall.setAttribute("y2", Integer.toString(y2));							
											walls.appendChild(wall);
										}
										
										empty = true;
									}
								}
							}
						}
						
						/* Függőleges falak feltérképépezése */
						x1 = 0;
						x2 = 0;
						y1 = 0;
						y2 = 0;
						empty = true;
						
						for (int j = 0; j < 20; j++)	{
							for (int i = 0; i < 14; i++)	{							
								if(data[i][j].equals("wall"))	{
									int x = this.getCoordinateX(j);;									
									int y = this.getCoordinateY(i);
									
									if(empty)	{
										empty = false;
										x1 = x2 = x;
										y1 = y2 = y;
									}
									else	{
										x2 = x;
										y2 = y;
									}
									
									
								}
								else	{
									if(empty == false)	{
										if( x1 != x2 || y1 != y2)	{
											Element wall = doc.createElement("wall");
											wall.setAttribute("x1", Integer.toString(x1));
											wall.setAttribute("y1", Integer.toString(y1));
											wall.setAttribute("x2", Integer.toString(x2));
											wall.setAttribute("y2", Integer.toString(y2));							
											walls.appendChild(wall);
										}										
										
										empty = true;
									}
								}
							}
						}


						// Ellenségek
						Element enemies = doc.createElement("enemies");
						rootElement.appendChild(enemies);
						
						// Vízszintes mozgás feltérképezése						
						empty = true;
						Element enemy = doc.createElement("enemy");
						
						for (int i = 0; i < 14; i++)	{
							for (int j = 0; j < 20; j++)	{
								if(data[i][j].equals("enemy"))	{
									int x = this.getCoordinateX(j);									
									int y = this.getCoordinateY(i);			
																		
																											
									if(empty)	{
										enemy = doc.createElement("enemy");						
										
										Element position = doc.createElement("position");
										position.setAttribute("x", Integer.toString(x));
										position.setAttribute("y", Integer.toString(y));
										enemy.appendChild(position);

										empty = false;										
									}
									else	{
										Element position = doc.createElement("position");
										position.setAttribute("x", Integer.toString(x));
										position.setAttribute("y", Integer.toString(y));
										enemy.appendChild(position);
									}
									
									
								}								
								else if(empty == false)	{
									if(enemy.getChildNodes().getLength() > 1)	{
										enemies.appendChild(enemy);									
									}
									empty = true;																		
								}
							}
						}
						
						
						/* Függőleges mozgás feltérképépezése */
						empty = true;
						enemy = doc.createElement("enemy");
						
						for (int j = 0; j < 20; j++)	{						
							for (int i = 0; i < 14; i++)	{							
								if(data[i][j].equals("enemy"))	{
									int x = this.getCoordinateX(j);									
									int y = this.getCoordinateY(i);
																		
																											
									if(empty)	{
										enemy = doc.createElement("enemy");						
										
										Element position = doc.createElement("position");
										position.setAttribute("x", Integer.toString(x));
										position.setAttribute("y", Integer.toString(y));
										enemy.appendChild(position);

										empty = false;										
									}
									else	{
										Element position = doc.createElement("position");
										position.setAttribute("x", Integer.toString(x));
										position.setAttribute("y", Integer.toString(y));
										enemy.appendChild(position);
									}
									
									
								}								
								else if(empty == false)	{
									if(enemy.getChildNodes().getLength() > 1)	{
										enemies.appendChild(enemy);									
									}
									empty = true;																		
								}
							}
						}						

						// write the content into xml file
						TransformerFactory transformerFactory = TransformerFactory.newInstance();
						Transformer transformer = transformerFactory.newTransformer();
						DOMSource source = new DOMSource(doc);
						StreamResult result = new StreamResult(w);
						//new File("C:\\file.xml")

						// Output to console for testing
						//StreamResult result = new StreamResult(System.out);

						transformer.transform(source, result);

						System.out.println("File saved!");
						
						JOptionPane.showMessageDialog(null, "A pálya mentése sikeresen megtörtént!", "Mentés", JOptionPane.PLAIN_MESSAGE);

					} 
					catch (Exception e) {
						e.printStackTrace();
					}			
				}  
    }//GEN-LAST:event_jSaveMenuActionPerformed

    private void jLoadMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jLoadMenuActionPerformed
// TODO add your handling code here:
            mapeditor.OpenDlg dlg = new OpenDlg(this, true, true);
            dlg.setVisible(true);
            File f=dlg.getFile();
            if (f != null) {                
								try {
 
									File fXmlFile = f;
									DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
									DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
									Document doc = dBuilder.parse(fXmlFile);

									//optional, but recommended
									//read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
									doc.getDocumentElement().normalize();

									System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

									int start_x = Integer.parseInt(((Element) doc.getElementsByTagName("start").item(0)).getAttribute("x"));
									int start_y = Integer.parseInt(((Element) doc.getElementsByTagName("start").item(0)).getAttribute("y"));
									
									int goal_x = Integer.parseInt(((Element) doc.getElementsByTagName("goal").item(0)).getAttribute("x"));
									int goal_y = Integer.parseInt(((Element) doc.getElementsByTagName("goal").item(0)).getAttribute("y"));
									
									start_x = this.getIndexJ(start_x);
									start_y = this.getIndexI(start_y);
																		
									goal_x = this.getIndexJ(goal_x);									
									goal_y = this.getIndexI(goal_y);
													
									//int x = (10 - j - 1) * -50;									
									//int y = (7 - i) * 50;
									
									data[start_y][start_x] = "start";
									buttons[start_y][start_x].setIcon(start);
													
									data[goal_y][goal_x] = "end";
									buttons[goal_y][goal_x].setIcon(end);
									
									// Falak
									NodeList nList = doc.getElementsByTagName("wall");

									System.out.println("----------------------------");

									for (int temp = 0; temp < nList.getLength(); temp++) {

										Node nNode = nList.item(temp);

										//System.out.println("\nAktualis :" + nNode.getNodeName());

										if (nNode.getNodeType() == Node.ELEMENT_NODE) {

											Element eElement = (Element) nNode;

											System.out.println("X1 : " + eElement.getAttribute("x1"));
											System.out.println("Y1 : " + eElement.getAttribute("y1"));
											System.out.println("X2 : " + eElement.getAttribute("x2"));
											System.out.println("Y2 : " + eElement.getAttribute("y2"));
											
											
											int x1 = Integer.parseInt(eElement.getAttribute("x1"));
											int x2 = Integer.parseInt(eElement.getAttribute("x2"));
											int y1 = Integer.parseInt(eElement.getAttribute("y1"));
											int y2 = Integer.parseInt(eElement.getAttribute("y2"));											
											
											if(x1 == x2)	{
												while(y1 >= y2)	{																										
													int i = this.getIndexI(y1);
													int j = this.getIndexJ(x1);
													
													buttons[i][j].setIcon(wall);
													data[i][j] = "wall";
													
													y1 -= 50;
												}
											}
											else	{
												while(x1 <= x2)	{																										
													int i = this.getIndexI(y1);
													int j = this.getIndexJ(x1);
													
													buttons[i][j].setIcon(wall);
													data[i][j] = "wall";
													
													x1 += 50;
												}
											}												
										}
									}
									
									// Ellenfelek
									nList = doc.getElementsByTagName("position");

									//System.out.println("----------------------------");

									for (int temp = 0; temp < nList.getLength(); temp++) {

										Node nNode = nList.item(temp);

										//System.out.println("\nAktualis :" + nNode.getNodeName());

										if (nNode.getNodeType() == Node.ELEMENT_NODE) {

											Element eElement = (Element) nNode;

											//System.out.println("X : " + eElement.getAttribute("x"));
											//System.out.println("Y : " + eElement.getAttribute("y"));											
											
											int i = this.getIndexI(Integer.parseInt(eElement.getAttribute("y")));
											int j = this.getIndexJ(Integer.parseInt(eElement.getAttribute("x")));
											
											buttons[i][j].setIcon(enemy);
											data[i][j] = "enemy";											
										}
									}
									
									JOptionPane.showMessageDialog(null, "A pálya sikeresen betöltve!", "Megnyitás", JOptionPane.PLAIN_MESSAGE);
								}	
								catch (Exception e) {
									e.printStackTrace();
								}                
            }
                    
            
    }//GEN-LAST:event_jLoadMenuActionPerformed

    private void jFileMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jFileMenuActionPerformed
// TODO add your handling code here:
    
    }//GEN-LAST:event_jFileMenuActionPerformed

    private void jQuitMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jQuitMenuActionPerformed
// TODO add your handling code here:
        this.setVisible(false);
        this.dispose();
    }//GEN-LAST:event_jQuitMenuActionPerformed

  private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
    // TODO add your handling code here:
		for (int i = 0; i < 14; i++)	{
			for (int j = 0; j < 20; j++)	{
				data[i][j] = "none";
				buttons[i][j].setIcon(null);
			}
		}
  }//GEN-LAST:event_jMenuItem2ActionPerformed
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new mainWnd().setVisible(true);
            }
        });
    }
		
		// X tengely
		public static int getCoordinateX(int val)	{
			return (10 - val) * -50;
		}
		
		// Y tengely
		public static int getCoordinateY(int val)	{
			return (7 - val) * 50;
		}
		
		// Y tengely, 14 sor, 14x50 = 700px
		public static int getIndexI(int val)	{
			return 7-(val/50);									
		}
		
		// X tengely, 20 oszlop, 20x50 = 1000px
		public static int getIndexJ( int val)	{
			return 10-(val/-50);
		}
    
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JMenu jFileMenu;
  private javax.swing.JMenuItem jLoadMenu;
  private javax.swing.JMenuBar jMenuBar1;
  private javax.swing.JMenuItem jMenuItem1;
  private javax.swing.JMenuItem jMenuItem2;
  private javax.swing.JMenuItem jQuitMenu;
  private javax.swing.JMenuItem jSaveMenu;
  private javax.swing.JSeparator jSeparator1;
  // End of variables declaration//GEN-END:variables
    
}
